#include <stdlib.h>
#include <string.h>
#include "../include/string.h"
#include "../include/value.h"
#include "../include/pool.h"
#include "../include/line.h"
u_int Get_Hash_Of_Cstr(const u_byte *str, u_int *hashcode)
{
    *hashcode = 0;
    u_int i = 0;
    for (; str[i] != '\0'; i++)
    {
        *hashcode = *hashcode * 31 + str[i] + 1;
    }
    return i;
}

void Delete_String(Object *self)
{
    String *string = (String *)self;
    Globe_Free(string->array);
}

void String_Init(String *self, const u_byte *value)
{
    self->type = T_STRING;
    self->delete = Delete_String;
    self->length = Get_Hash_Of_Cstr(value, &self->hashCode);
    self->array = (u_byte *)Globe_Malloc(sizeof(u_byte) * self->length + 1);
    strcpy(self->array, value);
}

void String_Concat(String *self, String *str1, String *str2)
{
    self->type = T_STRING;
    self->delete = Delete_String;
    self->array = (u_byte *)Globe_Malloc(sizeof(u_byte) * (str1->length + str2->length) + 1);
    strcpy(self->array, str1->array);
    strcat(self->array, str2->array);
    self->length = Get_Hash_Of_Cstr(self->array, &self->hashCode);
}

// Object *String_New_Concat(Line *line, String *str1, String *str2)
// {
//     String *self = Globe_Malloc(sizeof(String));
//     String_Concat(self, str1, str2);
//     return (Object *)self;
// }

bool String_Equal(String *str1, String *str2)
{
    if (str1->hashCode != str2->hashCode)
    {
        return false;
    }
    return !strcmp(str1->array, str2->array);
}

String *String_New(Line *line,const u_byte* str)
{
    String *self = Globe_Malloc(sizeof(String));
    String_Init(self, str);
    return self;
}